#include "TrainSystem.h"

namespace train_system
{
    const string TrainSystem::TrainFileName = ".\\train.txt";
    const string TrainSystem::ManagerFileName = ".\\manager.txt";

    bool TrainSystem::addTrain(const string &number, const string &departure_station, const string &arrival_station, const string &departure_time)
    {
        if (_trains.find(number) != _trains.end())
        {
            return false;
        }

        _trains[number] = Train(number, departure_station, arrival_station, departure_time);
        return true;
    }

    bool TrainSystem::addTrain(string &&number, string &&departure_station, string &&arrival_station, string &&departure_time)
    {
        if (_trains.find(number) != _trains.end())
        {
            return false;
        }

        string temp(number);
        _trains[temp] = Train(std::move(number), std::move(departure_station), std::move(arrival_station), std::move(departure_time));
        return true;
    }

    bool TrainSystem::deleteTrain(const string &number)
    {
        if (_trains.find(number) == _trains.end())
        {
            return false;
        }

        _trains.erase(number);
        return true;
    }

    bool TrainSystem::updateTrain(const string &number, const string &departure_station, const string &arrival_station, const string &departure_time)
    {
        if (_trains.find(number) == _trains.end())
        {
            return false;
        }

        _trains[number] = Train(number, departure_station, arrival_station, departure_time);
        return true;
    }

    bool TrainSystem::updateTrain(string &&number, string &&departure_station, string &&arrival_station, string &&departure_time)
    {
        if (_trains.find(number) == _trains.end())
        {
            return false;
        }

        string temp(number);
        _trains[temp] = Train(std::move(number), std::move(departure_station), std::move(arrival_station), std::move(departure_time));
        return true;
    }

    void TrainSystem::showTrain(const string &number) const
    {
        if (_trains.find(number) == _trains.end())
        {
            cout << "车次不存在。" << endl;
            return;
        }

        cout << "车次信息如下:" << endl;
        const Train &train = _trains.at(number);
        cout << "车次编号: " << train.getNumber() << endl;
        cout << "起始站台: " << train.getDepartureStation() << endl;
        cout << "终点站台: " << train.getArrivalStation() << endl;
        cout << "出发时间: " << train.getDepartureTime() << endl;
    }

    bool TrainSystem::saveTrain(const string &file_name) const
    {
        ofstream file(file_name, ios_base::out | ios_base::trunc);
        if (!file.is_open())
        {
            return false;
        }

        for (const auto &train : _trains)
        {
            file << train.second.getNumber() << " " << train.second.getDepartureStation() << " " << train.second.getArrivalStation() << " " << train.second.getDepartureTime() << endl;
        }

        file.close();

        return true;
    }

    bool TrainSystem::loadTrain(const string &file_name)
    {
        ifstream file(file_name);
        if (!file.is_open())
        {
            return false;
        }

        string number;
        string departure_station;
        string arrival_station;
        string departure_time;
        while (file >> number >> departure_station >> arrival_station >> departure_time)
        {
            _trains[number] = Train(number, departure_station, arrival_station, departure_time);
        }

        file.close();

        return true;
    }

    bool TrainSystem::saveManager(const string &file_name) const
    {
        ofstream file(file_name, ios_base::out | ios_base::trunc);
        if (!file.is_open())
        {
            return false;
        }

        for (const auto &manager : _managers)
        {
            file << manager.second.getId() << " " << manager.second.getPassword() << endl;
        }

        file.close();

        return true;
    }

    bool TrainSystem::loadManager(const string &file_name)
    {
        ifstream file(file_name);
        if (!file.is_open())
        {
            return false;
        }

        string id;
        string password;
        while (file >> id >> password)
        {
            _managers[id] = Manager(id, password);
        }

        file.close();

        return true;
    }

    bool TrainSystem::login(const string &id, const string &password)
    {
        if (_managers.find(id) == _managers.end())
        {
            return false;
        }

        return _managers.at(id) == Manager(id, password);
    }

    void TrainSystem::menu()
    {
        cout << "****************车次信息管理系统******************" << endl;
        cout << "********        1. 添加车次信息           ********" << endl;
        cout << "********        2. 删除车次信息           ********" << endl;
        cout << "********        3. 更新车次信息           ********" << endl;
        cout << "********        4. 显示特定车次信息       ********" << endl;
        cout << "********        5. 显示全部车次信息       ********" << endl;
        cout << "********        6. 退出系统               ********" << endl;
        cout << "**************************************************" << endl;
    }

    void TrainSystem::showAllTrain() const
    {
        cout << "所有车次信息如下:" << endl;
        for (const auto &train : _trains)
        {
            cout << "车次编号: " << train.second.getNumber() << endl;
            cout << "起始站台: " << train.second.getDepartureStation() << endl;
            cout << "终点站台: " << train.second.getArrivalStation() << endl;
            cout << "出发时间: " << train.second.getDepartureTime() << endl;
            cout << endl;
        }
    }

    void TrainSystem::addManager(const string &id, const string &password)
    {
        _managers[id] = Manager(id, password);
    }

    void TrainSystem::initSystem()
    {
        // system("title 火车售票系统"); // 设置控制台标题
        // system("chcp 65001"); // 将控制台字符编码设置为UTF-8
        
        SetConsoleCP(65001);          // 将控制台字符编码设置为UTF-8
        SetConsoleOutputCP(65001);    // 将控制台字符编码设置为UTF-8

        cout << "温馨提示：请不要输入中文字符。" << endl;

        loadTrain(TrainFileName);
        loadManager(ManagerFileName);
    }

    void TrainSystem::closeSystem()
    {
        saveTrain(TrainFileName);
        saveManager(ManagerFileName);
    }

    void TrainSystem::pauseSystem()
    {
        cout << "请按任意键继续..." << endl;
        getchar();
        getchar();
    }

    bool TrainSystem::login(int count)
    {
        cout << "欢迎来到车次管理系统" << endl;
        cout << "请输入您的账号和密码以登录。" << endl;

        do
        {
            string id, password;
            cout << "账号: ";
            cin >> id;
            cout << "密码: ";
            cin >> password;

            if (this->login(id, password))
            {
                cout << "登录成功！" << endl;
                this->pauseSystem();
                return true;
            }
            else
            {
                cout << "登录失败！" << endl;
                cout << "您还有" << --count << "次机会。" << endl
                     << endl;
            }
        } while (count > 0);

        return false;
    }

    void TrainSystem::run()
    {
        for (;;)
        {
            this->clear();

            this->menu();
            cout << "请选择:";
            int choice;
            cin >> choice;

            switch (choice)
            {
            case 1:
            {
                string number, departure_station, arrival_station, departure_time;
                cout << "请输入车次编号:";
                cin >> number;
                cout << "请输入车次的出发站台:";
                cin >> departure_station;
                cout << "请输入车次的到达站台:";
                cin >> arrival_station;
                cout << "请输入车次的出发时间:";
                cin >> departure_time;

                if (this->addTrain(number, departure_station, arrival_station, departure_time))
                {
                    cout << "添加车次成功。";
                }
                else
                {
                    cout << "添加车次失败。车次已存在。";
                }
                break;
            }

            case 2:
            {
                string number;
                cout << "请输入车次编号:";
                cin >> number;

                if (this->deleteTrain(number))
                {
                    cout << "删除车次成功。";
                }
                else
                {
                    cout << "删除车次失败。车次不存在。";
                }
                break;
            }

            case 3:
            {
                string number, departure_station, arrival_station, departure_time;
                cout << "请输入车次编号:";
                cin >> number;
                cout << "请输入车次的出发站台:";
                cin >> departure_station;
                cout << "请输入车次的到达站台:";
                cin >> arrival_station;
                cout << "请输入车次的出发时间:";
                cin >> departure_time;

                if (this->updateTrain(number, departure_station, arrival_station, departure_time))
                {
                    cout << "更新车次成功。";
                }
                else
                {
                    cout << "更新车次失败。车次不存在。";
                }
                break;
            }

            case 4:
            {
                string number;
                cout << "请输入车次编号:";
                cin >> number;

                this->showTrain(number);
                break;
            }

            case 5:
            {
                this->showAllTrain();
                break;
            }

            case 6:
            {
                cout << "系统即将关闭, 感谢您的使用。" << endl;
                this->pauseSystem();
                return;
            }

            default:
                cout << "输入有误，请重新输入。";
                break;
            }
            this->pauseSystem();
        }
    }

    void TrainSystem::clear()
    {
        system("cls");
    }
} //@end namespace train_system